/**
 * 
 */
package cn.com.gzheroli.core.util.docx4j;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.docx4j.dml.chart.CTAxDataSource;
import org.docx4j.dml.chart.CTBarChart;
import org.docx4j.dml.chart.CTBarSer;
import org.docx4j.dml.chart.CTExtensionList;
import org.docx4j.dml.chart.CTNumData;
import org.docx4j.dml.chart.CTNumDataSource;
import org.docx4j.dml.chart.CTNumRef;
import org.docx4j.dml.chart.CTNumVal;
import org.docx4j.dml.chart.CTRadarChart;
import org.docx4j.dml.chart.CTRadarSer;
import org.docx4j.dml.chart.CTSerTx;
import org.docx4j.dml.chart.CTStrData;
import org.docx4j.dml.chart.CTStrRef;
import org.docx4j.dml.chart.CTStrVal;
import org.docx4j.dml.chart.CTUnsignedInt;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.io.SaveToZipFile;
import org.docx4j.openpackaging.packages.SpreadsheetMLPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.DrawingML.Chart;
import org.docx4j.openpackaging.parts.SpreadsheetML.WorksheetPart;
import org.docx4j.openpackaging.parts.WordprocessingML.EmbeddedPackagePart;
import org.docx4j.utils.BufferUtil;
import org.docx4j.wml.ObjectFactory;
import org.xlsx4j.sml.Cell;
import org.xlsx4j.sml.Row;
import org.xlsx4j.sml.STCellType;

/**
 * @author lichangrong
 *
 */
public class DocChart {

	/**
	 * @param args
	 */

	public static void main(String[] args) throws Docx4JException {
		//WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(DocChart.class.getClassLoader().getResourceAsStream("tpl.docx"));
		WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File("/Users/lichangrong/Documents/tpl.docx"));
		// ChartData data = new ChartData();
		ObjectFactory factory = new org.docx4j.wml.ObjectFactory();
		List<Object> paragraphs = wordMLPackage.getMainDocumentPart().getContent();
		HashMap<PartName, Part> parts = wordMLPackage.getParts().getParts();
		Iterator<Map.Entry<PartName, Part>> iterator = parts.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<PartName, Part> entry = iterator.next();
			PartName partName = entry.getKey();
			Part part = entry.getValue();

			// parts.forEach((partName, part){
			if (partName.getName().toLowerCase().indexOf("excel") > 0) {// s
				System.out.println(part.getClass().getName());
			} //
			if (partName.getName().indexOf("charts") > 0 && (part instanceof Chart)) {
				Chart chart = (Chart) part;
				List<Object> objects;
				try {
					objects = chart.getContents().getChart().getPlotArea().getAreaChartOrArea3DChartOrLineChart();
					if (objects.size() >= 1) {
						for (Object obj : objects) {
							// objects.forEach((obj) -> {
							if (obj instanceof CTBarChart) {
								CTBarChart ctRadarChart = (CTBarChart) obj;
								String str = partName.getName();
								str = str.substring(str.lastIndexOf("/") + 1);
								System.out.println("-----------------========"+str);
								DocChart._renderCTBarChart(ctRadarChart,
										Arrays.asList(Arrays.asList("12", "23"), Arrays.asList("89", "56")),
										Arrays.asList("A", "b"), Arrays.asList("A11", "b11"));
							}
						}
					}
				} catch (Docx4JException e) {
					e.printStackTrace();
				}
			}
		} // end
			// if
			// });

		EmbeddedPackagePart epp = (EmbeddedPackagePart) wordMLPackage.getParts()
				.get(new PartName("/word/embeddings/Microsoft_Excel____1.xlsx"));
		if (epp == null) {
			throw new Docx4JException("Could find EmbeddedPackagePart:/word/embeddings/Microsoft_Excel____1.xlsx ");
		}
		InputStream is = BufferUtil.newInputStream(epp.getBuffer());
		SpreadsheetMLPackage spreadSheet = (SpreadsheetMLPackage) SpreadsheetMLPackage.load(is);
		Map<PartName, Part> partsMap = spreadSheet.getParts().getParts();
		Iterator<Entry<PartName, Part>> it = partsMap.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry<PartName, Part> pairs = it.next();
			if (partsMap.get(pairs.getKey()) instanceof WorksheetPart) {
				WorksheetPart wsp = (WorksheetPart) partsMap.get(pairs.getKey());
				List<Row> rows = wsp.getJaxbElement().getSheetData().getRow();
				for (Row row : rows) {
					List<Cell> cells = row.getC();
					for (Cell cell : cells) {
						if (cell.getR().equals("B2"))  {//&& cell.getV() != null)
							if(cell.getV() != null)
							System.out.println("B2 CELL VAL: " + cell.getV());
							// change the B2 cell value
							cell.setT(STCellType.N);
							cell.setV("3");
						} else if (cell.getR().equals("B3"))  {//&& cell.getV() != null)
							if(cell.getV() != null)
							System.out.println("B3 CELL VAL: " + cell.getV());
							// Change the B3 cell value
							cell.setT(STCellType.N);
							cell.setV("3");
						}
					}
				}
			}
		}
		// }
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		SaveToZipFile saver = new SaveToZipFile(spreadSheet);
		saver.save(baos);
		epp.setBinaryData(baos.toByteArray());
		wordMLPackage.save(new File("./sss.docx"));
	}

	private static void _renderCTBarChart(CTBarChart chart, List<List<String>> data, List<String> strName,
			List<String> txList) {
		List<CTBarSer> list = chart.getSer();
		int ii = 0;
		while (data.size() > list.size()) {
			CTBarSer ser = new CTBarSer();
			CTUnsignedInt index = new CTUnsignedInt();
			index.setVal(list.size());
			CTSerTx tx = new CTSerTx();
			CTStrRef cTStrReftx = new CTStrRef();
			cTStrReftx.setF("");
			cTStrReftx.setExtLst(new CTExtensionList());
			cTStrReftx.setStrCache(new CTStrData());
			tx.setStrRef(cTStrReftx);
			ser.setTx(tx);
			CTNumDataSource CTNumDataSource = new CTNumDataSource();
			CTNumRef CTNumRef = new CTNumRef();
			CTNumRef.setF("");
			CTNumRef.setExtLst(new CTExtensionList());
			CTNumRef.setNumCache(new CTNumData());
			CTNumDataSource.setNumRef(CTNumRef);
			// CTNumDataSource
			ser.setVal(CTNumDataSource); // ser.s
			CTAxDataSource CTAxDataSource = list.get(ii).getCat();
			ser.setCat(CTAxDataSource);
			ser.setIdx(index);
			ser.setOrder(index);

			ser.setInvertIfNegative(list.get(ii).getInvertIfNegative());
			ser.setSpPr(list.get(ii).getSpPr());
			list.add(ser);
			ii++;
		}

		for (int j = 0; j < list.size() && j < data.size(); j++) {
			// 值
			List<CTNumVal> ctNumVals = list.get(j).getVal().getNumRef().getNumCache().getPt();
			// 横坐标
			List<CTStrVal> ctStrVals = list.get(j).getCat().getStrRef().getStrCache().getPt(); //
			List<CTStrVal> txStrVals = list.get(j).getTx().getStrRef().getStrCache().getPt();
			ctNumVals.clear();
			ctStrVals.clear();
			while (data.get(j).size() > ctNumVals.size()) {
				CTNumVal numVal = new CTNumVal();
				numVal.setIdx(ctNumVals.size());
				ctNumVals.add(ctNumVals.size(), numVal);
			}
			while (strName.size() > ctStrVals.size()) {
				CTStrVal strVal = new CTStrVal();
				strVal.setIdx(ctStrVals.size());
				ctStrVals.add(ctStrVals.size(), strVal);
			}
			if (txStrVals.size() < 1) {
				CTStrVal strVal = new CTStrVal();
				strVal.setIdx(txStrVals.size());
				txStrVals.add(txStrVals.size(), strVal);
			}
			txStrVals.get(0).setV(txList.get(j));
			for (int i = 0; i < data.get(j).size(); i++) {
				try {
					ctStrVals.get(i).setV(strName.get(i));
					ctNumVals.get(i).setV(String.valueOf(data.get(j).get(i)));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} //
	}

	private static void _renderCTRadarChart(CTRadarChart chart, List<String> data, List<String> name) {
		List<CTRadarSer> list = chart.getSer();
		for (int j = 0; j < list.size(); j++) {
			List<CTNumVal> ctNumVals = list.get(j).getVal().getNumRef().getNumCache().getPt();
			List<CTStrVal> ctStrVals = list.get(j).getCat().getStrRef().getStrCache().getPt();
			ctNumVals.clear();
			ctStrVals.clear();
			while (data.size() > ctNumVals.size()) {
				CTNumVal numVal = new CTNumVal();
				numVal.setIdx(ctNumVals.size());
				ctNumVals.add(ctNumVals.size(), numVal);
			}
			while (data.size() > ctStrVals.size()) {
				CTStrVal strVal = new CTStrVal();
				strVal.setIdx(ctStrVals.size());
				ctStrVals.add(ctStrVals.size(), strVal);
			}

			for (int i = 0; i < data.size(); i++) {
				ctStrVals.get(i).setV(name.get(i));
				ctNumVals.get(i).setV(String.valueOf(data.get(i)));
			}
		}
	}
}
